﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using WebUI.Models;
using WebUI.Infrastructure;
using Utils;
using DomainModel;
using WebUI.HtmlHelpers;
using WebUI.Utils;

namespace WebUI.Controllers
{
    public class AccountController : BaseController
    {
        [HttpGet]
        public ActionResult SignUp()
        {
            return View(new SignUpViewModel());
        }
        [HttpPost]
        [ValidateInput(false)]
        public ActionResult SignUp(SignUpViewModel model)
        {
            //pass the basic check
            if (ModelState.IsValid)
            {
                //check if username, email exists in db
                int checkResult = SqlUtilities.Query<int>(ConstUtils.SP_CheckUserNameAndEmail, new { Email = model.Email, UserName = model.UserName }).Single();
                //passed, insert into db, redirect to /account
                if (checkResult == 0)
                {
                    Login newLogin = null;
                    string confirmationKey = string.Empty;
                    try
                    {
                        confirmationKey = CommonUtilities.CreateGUIDKey();
                        newLogin = SqlUtilities.Query<Login>(ConstUtils.SP_InsertLoginAndInd, new
                        {
                            Email = model.Email,
                            PasswordHash = PasswordHash.CreateHash(model.Password),
                            UserName = model.UserName,
                            EmailConfirmationKey = confirmationKey,
                            FirstName = model.FirstName,
                            LastName = model.LastName,
                            Title = model.Title,
                            Location = model.Location
                        }, null, true).FirstOrDefault();
                    }
                    catch
                    {
                        newLogin = null;
                    }
                    if (newLogin == null || newLogin.LoginID <= 0)
                    {
                        CreateSessionMessageForError("Sorry, internal error occurred. Please try it again.");
                        return View(model);
                    }
                    else
                    { 
                        //send email and redirect to /account page
                        try
                        {
                            EmailUtils.Send(
                                GlobalUtilities.GetInstance().Email_NoReply,
                                model.Email,
                                EmailTemplateType.SignUp,
                                new string[] { model.FirstName + " " + model.LastName, model.Email, base.AbsoluteUrlForEmailConfirmation(model.Email, confirmationKey) },
                                newLogin.LoginID);
                            
                        }
                        catch
                        { }
                        //set up the Auth cookie
                        string authCookieValue = newLogin.LoginID.ToString() + "|" + newLogin.AccountID.ToString() + "|" + newLogin.AccountType;
                        FormsAuthentication.SetAuthCookie(authCookieValue, true);
                        //redirect
                        return RedirectToAction("EditAccountProfile");
                    }
                }
                else if (checkResult == 1)
                {
                    ModelState.AddModelError("Email", "This Email has been registered in our system.");
                }
                else if (checkResult == 2){
                    ModelState.AddModelError("UserName", "This User name has been taken in our system.");
                }
                else 
                {
                    ModelState.AddModelError("Email", "This Email has been registered in our system.");
                    ModelState.AddModelError("UserName", "This User name has been taken in our system.");
                }
                return View(model);
            }
            else
            {
                return View(model);
            }
        }

        public ActionResult SignIn()
        {
            return View(new SignInViewModel());
        }
       
        [HttpPost]
        [ValidateInput(false)]
        public ActionResult SignIn(SignInViewModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                var membership = (LoginMembershipProvider)Membership.Provider;
                if (membership.ValidateUser(model.UserName, model.Password))
                {
                    string authCookieValue = membership.LoginID.ToString() + "|" + membership.AccountID.ToString() + "|" + membership.AccountType;
                    FormsAuthentication.SetAuthCookie(authCookieValue, true);
                    if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                        && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
                    {
                        return Redirect(returnUrl);
                    }
                    else
                    {
                        //if ind logged in, go to /user/{UserName}
                        if (membership.AccountType == "i")
                        {
                            string url = Url.Action("Shots", "Ind", new { UserName = membership.UserName });
                            return Redirect(url);
                        }
                        //if co logged in, go to /co/jobs
                        else
                        {
                            return RedirectToAction("JobList", "Co");
                        }
                    }
                }
                else
                {
                    CreateSessionMessageForError("Invalid user name/email or password");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }

        public ActionResult SignOut()
        {
            FormsAuthentication.SignOut();

            return RedirectToAction("Index", "Home");
        }

        public ActionResult Email_Confirmation(string email, string key)
        {
            if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(key))
            {
                CreateSessionMessageForError("Email confirmation url is invalid or has expired.");
            }
            else
            {
                try
                {
                    int result = SqlUtilities.Query<int>(ConstUtils.SP_UpdateEmailConfirmed, new { Email = HttpUtility.UrlDecode(email), Key = key }, null, true).First();
                    if (result > 0)
                    {
                        CreateSessionMessageForSuccess("Your Email Address has been confirmed");
                    }
                    else 
                    {
                        CreateSessionMessageForError("Email confirmation url is invalid or has expired.");
                    }
                }
                catch
                {
                    CreateSessionMessageForError("Email confirmation url is invalid or has expired.");
                }
            }
            //go to /account
            return RedirectToAction("EditAccountProfile");
        }

        [Authorize]
        public ActionResult EditAccountProfile()
        {
            if (!base.IdentityWithoutUserName.IsLoggedIn)
            {
                return Redirect("/");
            }
            else
            {
                if (base.IdentityWithoutUserName.IsIndLoggedIn)
                {
                    return RedirectToAction("EditProfile", "Ind");
                }
                else
                {
                    return RedirectToAction("EditProfile", "Co");
                }
            }
        }

        public ActionResult ForgotPassword()
        {
            return View(new ForgotPasswordViewModel());
        }

        [HttpPost]
        public ActionResult ForgotPassword(ForgotPasswordViewModel model)
        {
            if (ModelState.IsValid)
            { 
                //check this email, if exists, then send out instruction email
                Login login = DataUtils.GetLoginByName(model.Email);
                if (login != null && login.LoginID > 0)
                { 
                    //send email and redirect to /account page
                    try
                    {
                        string newKey = CommonUtilities.CreateGUIDKey();
                        //update key
                        SqlUtilities.Execute(ConstUtils.SP_UpdatePasswordResetKey, new { Email = model.Email, Key = newKey });
                        //send email
                        EmailUtils.Send(
                            GlobalUtilities.GetInstance().Email_NoReply,
                            model.Email,
                            EmailTemplateType.ResetPassword,
                            new string[] { base.AbsoluteUrlForPasswordReset(model.Email, newKey) },
                            login.LoginID);

                    }
                    catch
                    { }
                    base.CreateSessionMessageForSuccess("Instructions to reset your password have been sent to you. Please check your email.");
                }
                else
                {
                    ModelState.AddModelError("Email", "This email address is not in our system");
                }
            }
            return View(model);
        }

        public ActionResult ResetPassword(string email, string key)
        {
            if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(key))
            {
                CreateSessionMessageForError("Password reset url is invalid or has expired. Try pasting the URL into your browser or requesting another password reset url.");
                return RedirectToAction("ForgotPassword");
            }
            else
            {
                try
                {
                    //verify email and key
                    int result = SqlUtilities.Query<int>(ConstUtils.SP_CheckPasswordResetKey, new { Email = HttpUtility.UrlDecode(email), Key = key }, null, true).First();
                    if (result > 0)
                    {
                        return View(new ResetPasswordViewModel());
                    }
                    else
                    {
                        CreateSessionMessageForError("Password reset url is invalid or has expired. Try pasting the URL into your browser or requesting another password reset url.");
                        return RedirectToAction("ForgotPassword");
                    }
                }
                catch
                {
                    CreateSessionMessageForError("Password reset url is invalid or has expired. Try pasting the URL into your browser or requesting another password reset url.");
                    return RedirectToAction("ForgotPassword");
                }
            }
        }

        [HttpPost]
        public ActionResult ResetPassword(ResetPasswordViewModel model)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    SqlUtilities.Execute(ConstUtils.SP_UpdatePasswordByEmailAndKey,
                        new { Email = HttpUtility.UrlDecode(model.Email), Key = model.Key, NewPasswordHash = PasswordHash.CreateHash(model.Password) }, null, true);
                    CreateSessionMessageForSuccess("Your password has been updated");
                    return Redirect("/");
                }
                catch
                {
                    CreateSessionMessageForError("Password reset url is invalid or has expired. Try requesting another password reset url.");
                    return RedirectToAction("ForgotPassword"); 
                }
            }
            else
            {
                return View(model);
            }
        }

        [HttpPost]
        [Authorize]
        public JsonResult Save(int loginID)
        {
            try
            {
                SqlUtilities.Execute(ConstUtils.SP_InsertSavedInd, new { SaveLoginID = IdentityWithoutUserName.LoginID, SavedLoginID = loginID }, null, true);
                return Json(JsonResultModelHelper.ForSuccess());
            }
            catch
            {
                return Json(JsonResultModelHelper.ForError());
            }
        }

        [HttpPost]
        [Authorize]
        public JsonResult Unsave(int loginID)
        {
            try
            {
                SqlUtilities.Execute(ConstUtils.SP_DeleteSavedInd, new { SaveLoginID = IdentityWithoutUserName.LoginID, SavedLoginID = loginID }, null, true);
                return Json(JsonResultModelHelper.ForSuccess());
            }
            catch
            {
                return Json(JsonResultModelHelper.ForError());
            }
        }
    }
}
